<?php

namespace App\Http\Controllers\Resource;

use Illuminate\Support\Facades\Log;

/**
 * 元阅读 数字资源
 *
 *  提供目录接口
 */
class YrdController extends CommonController
{
    public $tenantId = null;
    public $appId = '';
    public $secret = '65f941d3e4b03ff7ea275cec';
    public $privateKey = 'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALPltzZtq+9SmVwNohIUNCczn5uHfeKOdBJWys4+EdnFEyhjzwJRYnZYvSWd8cYMeomNO+CLOurc3JFBVMpKRi9QymlwSiHu7gwzjaRJvWc48zYKGvF9m2G541fdGds+IJu4yQSFMy8HPYI5mEdnhcQ8WnCRLv8BiO+Jkz+oj1L7AgMBAAECgYEAlTVhyYYbRiuXQY+ZLi+NtjoOFrzBf6ixwwgzu+4ldh8MLcLizsRby1b8wveGscJl3DLFSA+S9XvsgZnTTtld7bd7PI8aZgSTIOHh6r9MwbO6VALby0eSmF92K0uheJGxDVztizvAjDrC1bj6qjic52JvPbNy7yud6+w58j3VZtECQQD1cijBwiyeQ6h2/tu1/lyit6qtA3qvPyaQsgu/yumJK7i5LTj4UfU7KS++D3vGtBLjhlT5Ibg5Bx6m+c4gpVYjAkEAu6IBQE7E2nfKysW0NjdBBxCu+g8amFKm6plv78qIXcnNkK3RaZF1kyKffEgHKmx7vZx0KNdJkZe49ayFF0fhSQJAXMGSs36tG/ZXsPipkYKaAYhFgPLip13HNkGC/S0yynryaVC0yes3MO9ksn/pd/NPfBqk/C2JEEwnglS/WEkDXwJBAJeBKq14bO9SxwaQOQGGABXqXL9BLuJL6seHeaEP0qiYaEoob+1kLKHP1SOPLWoOCqSCDjFkFN1gu1J0KUsxGTECQHsftmIm2W/VajXj7lMZeweAQq/GHz/knyt52m0F6/4orlPWKlr9VMhY3fa/d4QT3UKfYPIWO6C55EUuWgeuHos=';
    public $host_url = 'https://api.metareader.cn';

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 获取所有数据（机构全量书籍ID）
     *         bookType //资源类型,示例值(EPUB:电⼦书;MP3:听书)
     *         page //当前⻚,示例值(1)
     *         size  //⻚⾯⼤⼩,示例值(10)
     *
     */
    public function getResourceList($book_type = 'EPUB', $page = 1, $limit = 100)
    {
        $url = $this->host_url . '/api/open/book/bookIds';

        $param = [
            'bookType' => $book_type,
            'page' => $page,
            'size' => $limit,
        ];

        //header头数据
        $header_data = [
            "tenantId" => $this->tenantId,
            "appId" => $this->appId,
            "timestamp" => time() . '000',
            "nonce" => get_guid(),
        ];
        $sign = $this->getSign($header_data);
        $header_data['sign'] = $sign;
        $result = $this->requestUrl($url, json_encode($param), 60, true, $header_data);
        $result = json_decode($result, true);

        //$result['data']['records']  这个接口数据在  $result['data']['records'] ，不直接在  data下
        if ((empty($result['data']['records']) || $result['code'] !== 0) || $result['isSuccess'] !== true) {
            Log::channel('yrdlog')->debug('获取所有资源失败');
            Log::channel('yrdlog')->debug($param);
            Log::channel('yrdlog')->debug($result);
            Log::channel('yrdlog')->debug('--------------------------------------------------------');
            return []; //没数据时，返回的false
        }
        return  $result; //返回所有，因为要总条数
    }
    /**
     * 获取资源详情(批量获取书籍详情)
     *         book_ids //资源ID集合最多1000个,传参时没有bookIds示例:[1,2,3]
     *
     */
    public function getResourceDetail($book_ids)
    {
        $url = $this->host_url . '/api/open/book/bookInfos';
        $param = $book_ids;

        //header头数据
        $header_data = [
            "tenantId" => $this->tenantId,
            "appId" => $this->appId,
            "timestamp" => time() . '000',
            "nonce" => get_guid(),
        ];
        $sign = $this->getSign($header_data);
        $header_data['sign'] = $sign;
        $result = $this->requestUrl($url, json_encode($param), 60, true, $header_data);
        $result = json_decode($result, true);
        if ((empty($result['data']) || $result['code'] !== 0) || $result['isSuccess'] !== true) {
            Log::channel('yrdlog')->debug('获取所有资源失败');
            Log::channel('yrdlog')->debug($param);
            Log::channel('yrdlog')->debug($result);
            Log::channel('yrdlog')->debug('--------------------------------------------------------');
            return []; //没数据时，返回的false
        }
        return  $result;
    }

    /**
     * 增量书籍ID
     *         book_type //资源类型,示例值(EPUB:电⼦书;MP3:听书;HTML:HTML⽂件;outer-sklib:社科社资源)
     *
     *         startDate  //开始⽇期yyyy-mm-dd
     *         endDate  //结束⽇期yyyy-mm-dd
     *
     */
    public function getResourceIncreaseList($book_type = 'EPUB', $start_time = '', $end_time = '')
    {
        $url = $this->host_url . '/api/open/book/increment/bookIds';
        $param = [
            'bookType' => $book_type,
            'startDate' => $start_time, //上一次更新时间
            'endDate' => $end_time, //本次开始更新时间
        ];

        //header头数据
        $header_data = [
            "tenantId" => $this->tenantId,
            "appId" => $this->appId,
            "timestamp" => time() . '000',
            "nonce" => get_guid(),
        ];
        $sign = $this->getSign($header_data);
        $header_data['sign'] = $sign;
        $result = $this->requestUrl($url, json_encode($param), 60, true, $header_data);
        $result = json_decode($result, true);
        if ((empty($result['data']) || $result['code'] !== 0) || $result['isSuccess'] !== true) {
            Log::channel('yrdlog')->debug('获取增量资源失败');
            Log::channel('yrdlog')->debug($param);
            Log::channel('yrdlog')->debug($result);
            Log::channel('yrdlog')->debug('--------------------------------------------------------');
            return []; //没数据时，返回的false
        }
        return  $result;
    }

    /**
     * 获取下架数据
     *         book_type //资源类型,示例值(EPUB:电⼦书;MP3:听书;HTML:HTML⽂件;outer-sklib:社科社资源)
     *
     *         startDate  //开始⽇期yyyy-mm-dd
     *         endDate  //结束⽇期yyyy-mm-dd
     *
     */
    public function downResourceList($book_type = 'EPUB', $start_time = '', $end_time = '')
    {
        $url = $this->host_url . '/api/open/book/decrement/bookIds';

        $param = [
            'bookType' => $book_type,
            'startDate' => $start_time, //上一次更新时间
            'endDate' => $end_time, //本次开始更新时间
        ];

        //header头数据
        $header_data = [
            "tenantId" => $this->tenantId,
            "appId" => $this->appId,
            "timestamp" => time() . '000',
            "nonce" => get_guid(),
        ];
        $sign = $this->getSign($header_data);
        $header_data['sign'] = $sign;
        $result = $this->requestUrl($url, json_encode($param), 60, true, $header_data);
        $result = json_decode($result, true);
        if ((empty($result['data']) || $result['code'] !== 0) || $result['isSuccess'] !== true) {
            Log::channel('yrdlog')->debug('获取下架资源失败');
            Log::channel('yrdlog')->debug($param);
            Log::channel('yrdlog')->debug($result);
            Log::channel('yrdlog')->debug('--------------------------------------------------------');
            return []; //没数据时，返回的false
        }
        return  $result;
    }

    /**
     * 获取更新数据
     *         book_type //资源类型,示例值(EPUB:电⼦书;MP3:听书;HTML:HTML⽂件;outer-sklib:社科社资源)
     *
     *         startDate  //开始⽇期yyyy-mm-dd
     *         endDate  //结束⽇期yyyy-mm-dd
     *
     */
    public function changeResourceList($book_type = 'EPUB', $start_time = '', $end_time = '')
    {
        $url = $this->host_url . '/api/open/book/updated/bookIds';

        $param = [
            'bookType' => $book_type,
            'startDate' => $start_time, //上一次更新时间
            'endDate' => $end_time, //本次开始更新时间
        ];

        //header头数据
        $header_data = [
            "tenantId" => $this->tenantId,
            "appId" => $this->appId,
            "timestamp" => time() . '000',
            "nonce" => get_guid(),
        ];
        $sign = $this->getSign($header_data);
        $header_data['sign'] = $sign;
        $result = $this->requestUrl($url, json_encode($param), 60, true, $header_data);
        $result = json_decode($result, true);

        if ((empty($result['data']) || $result['code'] !== 0) || $result['isSuccess'] !== true) {
            Log::channel('yrdlog')->debug('获取下架资源失败');
            Log::channel('yrdlog')->debug($param);
            Log::channel('yrdlog')->debug($result);
            Log::channel('yrdlog')->debug('--------------------------------------------------------');
            return []; //没数据时，返回的false
        }
        return  $result;
    }




    /**
     *获取目录接口
     * @param bookId 书ID
     */
    public function getBookCatalogue($book_id)
    {
        $url = $this->host_url . '/api/open/book/catalogue?bookId=' . $book_id; //获取电子书章节

        $param = []; //不能删除

        //header头数据
        $header_data = [
            "tenantId" => $this->tenantId,
            "appId" => $this->appId,
            "timestamp" => time() . '000',
            "nonce" => get_guid(),
        ];
        $sign = $this->getSign($header_data);
        $header_data['sign'] = $sign;
        $result = $this->requestUrl($url, json_encode($param), 60, true, $header_data);
        $result = json_decode($result, true);
        if ((empty($result['data']) || $result['code'] !== 0) || $result['isSuccess'] !== true) {
            Log::channel('yrdlog')->debug('获取下架资源失败');
            Log::channel('yrdlog')->debug($param);
            Log::channel('yrdlog')->debug($result);
            Log::channel('yrdlog')->debug('--------------------------------------------------------');
            return []; //没数据时，返回的false
        }
        $data = [];
        foreach ($result['data'] as $key => $val) {
            $data['data'][$key]['resource_business_id'] = 9;
            $data['data'][$key]['book_id'] = $val['bookId'];
            $data['data'][$key]['parent_id'] = $val['parentId'] ?? null; //父类id
            $data['data'][$key]['sort'] = !empty($val['sortValue']) ? $val['sortValue'] : $val['playOrder']; //排序
            $data['data'][$key]['media_type'] = $val['mediaType'] ?? null; //前⼀章⽬录ID
            $data['data'][$key]['pre_id'] = $val['preId']; //前⼀章⽬录ID
            $data['data'][$key]['next_id'] = $val['nextId']; //下⼀章⽬录ID
            $data['data'][$key]['href'] = $val['href'] ?? null; //相对路径，⾳频没有
            $data['data'][$key]['fragment_id'] = $val['fragmentId'] ?? null;
            $data['data'][$key]['level'] = $val['treeGrade'] ?? 0; //层级0，1，2，⾳频没有
            $data['data'][$key]['date'] = $val['date'] ?? null; //音频时间   音频才有
            $data['data'][$key]['chapter_id'] = $val['id'];
            $data['data'][$key]['chapter_name'] = $val['name'];
            $data['data'][$key]['chapter_duration'] = $val['duration'] ?? null; //时长 音频才有
            $data['data'][$key]['chapter_size'] = $val['size'] ?? null; //大小    音频才有
            $data['data'][$key]['audio_url'] = $val['aacPath'] ?? null; //音频地址   音频才有
            if (!empty($val['children'])) {
                foreach ($val['children'] as $k => $v) {
                    $data['data'][$key]['children'][$k]['book_id'] = $v['bookId'];
                    $data['data'][$key]['children'][$k]['parent_id'] = $v['parentId'];
                    $data['data'][$key]['children'][$k]['sort'] = !empty($v['sortValue']) ? $v['sortValue'] : $v['playOrder']; //排序
                    $data['data'][$key]['children'][$k]['pre_id'] = $v['preId']; //前⼀章⽬录ID
                    $data['data'][$key]['children'][$k]['next_id'] = $v['nextId']; //下⼀章⽬录ID
                    $data['data'][$key]['children'][$k]['href'] = $v['href'] ?? 0; //相对路径，⾳频没有
                    $data['data'][$key]['children'][$k]['level'] = $v['treeGrade'] ?? 0; //层级0，1，2，⾳频没有
                    $data['data'][$key]['children'][$k]['chapter_id'] = $v['id'];
                    $data['data'][$key]['children'][$k]['chapter_name'] = $v['name'];
                    $data['data'][$key]['children'][$k]['chapter_duration'] = $v['duration'] ?? null; //时长
                    $data['data'][$key]['children'][$k]['chapter_size'] = $v['size'] ?? null; //大小
                    $data['data'][$key]['children'][$k]['fragment_id'] = $v['fragmentId'] ?? null;
                }
            } else {
                $data['data'][$key]['children'] = [];
            }
        }
        $data['total'] = count($result['data']);
        $data['per_page'] = 1;
        $data['current_page'] = 1;
        return  $data;
    }



    /**
     * 获取签名
     * @param $data
     */
    public function getSign($param = [])
    {
        $param = $this->arraySort($param);
        $params = http_build_query($param); //null 不参与拼接，但是 空字符串要参与拼接
        $sign = $this->privateEncrypt(urldecode($params), $this->privateKey); //签名中文不转码，传输中文需要转码  urldecode 中文按正常输出
        return $sign;
    }


    /**
     * 获取畅想之星跳转地址
     * @param $url  跳转地址
     * @param $user_info  用户信息  (需要开发一个接口，验证读者证号是否有效，只要这里有效即可)
     * @return string
     */
    public function getSkipUrl($url, $user_info)
    {
        $lib_id = $this->lib_id;
        $lib_code = $this->lib_code;
        $account = $user_info['tel'];
        $username = $user_info['nickname'];
        $nonce = uniqid(); //随机数
        $key = md5($account . '_' . $lib_id  . '_' .  $lib_code  . '_' .  $nonce);
        $url = urlencode($url);
        $url = 'https://ua.cxstar.com/uniauth/dxValLogin/las2CXStar?LibID=' . $lib_id . '&id=' . $account . '&name=' . $username . '&nonce=' . $nonce . '&key=' . $key . '&returnurl=' . $url;

        return $url;
    }



    /**
     * 字典序排序
     */
    public function arraySort(array $param)
    {
        ksort($param);
        reset($param);

        return $param;
    }


    /**
     * RAS 加密函数
     * @param string $data 待签名字符串
     * @param string $privateKey 接入方私钥（PKCS#8 Base64格式）
     * @return string|null Base64编码的加密结果
     */
    function privateEncrypt($data, $privateKey)
    {
        if (empty($data) || empty($privateKey)) {
            return null;
        }
        try {
            // Base64解码私钥
            $decodedKey = base64_decode($privateKey);
            $decodedKey = $privateKey;
            // 转换为PEM格式（添加头尾标识）
            $pem = "-----BEGIN PRIVATE KEY-----\n" .
                chunk_split($decodedKey, 64, "\n") .
                "-----END PRIVATE KEY-----";
            // 加载私钥
            $privateKeyResource = openssl_pkey_get_private($pem);
            if (!$privateKeyResource) {
                throw new \Exception('无效的私钥');
            }

            // 执行加密
            $encrypted = '';
            if (!openssl_private_encrypt(
                $data,
                $encrypted,
                $privateKeyResource,
                OPENSSL_PKCS1_PADDING
            )) {
                throw new \Exception('加密失败: ' . openssl_error_string());
            }

            // 释放密钥资源
            openssl_free_key($privateKeyResource);

            return base64_encode($encrypted);
        } catch (\Exception $e) {
            error_log("RSA 加密错误: " . $e->getMessage());
            return null;
        }
    }


    public function requestUrl($url, $params = null, $timeout = 10, $json = false, $header_data = [])
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);


        //获取授权失败增加 2021-06-18
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        if (!empty($params)) {
            if (is_array($params)) {
                $params = http_build_query($params);
            } //如果传的是数组，就要进行对参数进行 &拼接
            if ($json) {
                curl_setopt(
                    $ch,
                    CURLOPT_HTTPHEADER,
                    array(
                        'Content-Type: application/json',
                        'Content-Length: ' . strlen($params),
                        'tenantId: ' . $header_data['tenantId'],
                        'appId: ' . $header_data['appId'],
                        'timestamp: ' . $header_data['timestamp'],
                        'nonce: ' . $header_data['nonce'],
                        'sign: ' . $header_data['sign'],
                    )
                );
            }
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        }
        $body = curl_exec($ch);


        //获取请求状态码 测试时才打开
        //  $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        // if ($httpCode != 200) {
        //     die('Error: ' . $httpCode);
        // }

        //获取错误信息
        // if (!$result = curl_exec($ch)) {
        //     die('cURL error: ' . curl_error($ch));
        // }

        curl_close($ch);

        return $body;
    }


    /******************************************下面是生成前端阅读界面的签名，使用js代码改装******************************************************** */

    public function sort_ASCII($obj)
    {
        uksort($obj, function ($a, $b) {
            return strcmp($a, $b);
        });
        return $obj;
    }

    public function parameterSplicing($obj)
    {
        $items = array();
        foreach ($obj as $key => $value) {
            if (is_array($value)) {
                $value = json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
            }
            $items[] = $key . '=' . $value;
        }
        return implode('&', $items);
    }

    public function hex_md5($s)
    {
        $s = mb_convert_encoding($s, 'UTF-8');
        return bin2hex(md5($s, true));
    }

    public function readPageSign($params)
    {
        // 参数排序
        $sorted = $this->sort_ASCII($params);

        // 拼接参数
        $str = $this->parameterSplicing($sorted);

        // 生成signA
        $signA = strtoupper($this->hex_md5($str));

        // 生成signB
        $subStr = substr($signA, 4, 12);
        $signB = strtoupper($this->hex_md5($subStr));

        // 返回最终签名
        return substr($signB, 4, 16);
    }

    /**
     *  获取阅读界面地址
     *  "https://h5.metareader.cn/pages/book/read?bid=bid&appId=appId&href=href&fragmentId=fragmentId&tenantId=tenantId&timestamp=timestamp&userId=userId&sign=sign&toHome=1&navbar=1"
     */
    public function getReadPage($user_id, $book_id, $chapter_id, $href, $fragment_id)
    {
        //签名参数
        $data = [
            'appId' => $this->appId,
            'tenantId' => $this->tenantId,
            'timestamp' => time() . '000',
            'userId' => $user_id,
            'secret' => $this->secret,
        ];
        $sign = $this->readPageSign($data);
        $data['sign'] = $sign;
        $data['bid'] = $book_id;
        $data['href'] = $href;
        $data['fragmentId'] = $fragment_id;
        $data['toHome'] = 0; //是否显示回到首页按钮：1显示，0不显示，不传默认是显示的
        $data['navbar'] = 1; //是否显示标题栏：1显示，0不显示，不传默认是显示的

        // 构造查询参数
        $query = http_build_query($data);
        // 完整URL
        $url = "https://h5.metareader.cn/pages/book/read?" . $query;
        return $url;
    }
}
